﻿/* 2014/4/6 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cosmos.IO.FileSystemOperation
{
    /// <summary>
    /// Factory class of file system operator.
    /// </summary>
    public static class FileOperatorFactory
    {
        private const string NormalOperatorClassName = "Normal";
        private const string NormalOperatorDisplayName = ".Net";
        private const string WindowsOperatorClassName = "Windows";
        private const string WindowsOperatorDisplayName = "资源管理器";

        private static OperatorName[] _operatorNames = new OperatorName[]{
            new OperatorName(NormalOperatorClassName, NormalOperatorDisplayName),
            new OperatorName(WindowsOperatorClassName, WindowsOperatorDisplayName)
        };

        /// <summary>
        /// Creates an instance of default file operator class.
        /// </summary>
        /// <returns></returns>
        public static IFileSystemOperator CreateOperator()
        {
            return new FileSystemOperator();
        }

        /// <summary>
        /// Creates an instance of file operator class by specifying operator name.
        /// </summary>
        /// <param name="searcherName">Class name or display name of operator.</param>
        /// <returns>
        /// An object of file path operator class. If the operator name is invalid,
        /// return an instance of default file path operator class.
        /// </returns>
        public static IFileSystemOperator CreateOperator(string operatorName)
        {
            if (IsDisplayName(operatorName))
            {
                operatorName = GetClassName(operatorName);
            }

            IFileSystemOperator fileOperator = null;
            switch (operatorName)
            {
                case NormalOperatorClassName:
                    fileOperator = new FileSystemOperator(); break;
                case WindowsOperatorClassName:
                    fileOperator = new WindowsFileSystemOperator(); break;
                default:
                    fileOperator = new FileSystemOperator(); break;
            }
            return fileOperator;
        }

        /// <summary>
        /// Indicates whether the specified operator name is a class name.
        /// </summary>
        /// <param name="name">A operator name.</param>
        /// <returns>true if the the name is a class name; otherwise false.</returns>
        public static bool IsClassName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return false;

            foreach (string aClassName in ClassNames)
            {
                if (aClassName.Equals(name))
                    return true;
            }

            return false;
        }

        /// <summary>
        /// Indicates whether the specified operator name is a display name.
        /// </summary>
        /// <param name="name">A operator name.</param>
        /// <returns>true if the name is a display name; otherwise false.</returns>
        public static bool IsDisplayName(string name)
        {
            if (String.IsNullOrEmpty(name))
                return false;

            foreach (string aDisplayName in DisplayNames)
            {
                if (aDisplayName.Equals(name))
                    return true;
            }

            return false;
        }

        /// <summary>
        /// Gets corresponding class name of a display name.
        /// </summary>
        /// <param name="displayName">A display name.</param>
        /// <returns>Corresponding class name.</returns>
        public static string GetClassName(string displayName)
        {
            if (displayName == null)
                return null;

            foreach (OperatorName aName in _operatorNames)
            {
                if (displayName.Equals(aName.DispalyName))
                    return aName.ClassName;
            }

            return null;
        }

        /// <summary>
        /// Gets corresponding display name of a class name.
        /// </summary>
        /// <param name="className">A class name.</param>
        /// <returns>Corresponding display name.</returns>
        public static string GetDisplayName(string className)
        {
            if (className == null)
                return null;

            foreach (OperatorName aName in _operatorNames)
            {
                if (className.Equals(aName.ClassName))
                    return aName.DispalyName;
            }

            return null;
        }

        /// <summary>
        /// Gets all class names.
        /// </summary>
        public static IEnumerable<string> ClassNames
        {
            get
            {
                foreach (OperatorName aName in _operatorNames)
                    yield return aName.ClassName;
            }
        }

        /// <summary>
        /// Gets all display names.
        /// </summary>
        public static IEnumerable<string> DisplayNames
        {
            get
            {
                foreach (OperatorName aName in _operatorNames)
                    yield return aName.DispalyName;
            }
        }

        /// <summary>
        /// Represents file operator name.
        /// </summary>
        internal struct OperatorName
        {
            private string _className;
            private string _dispalyName;

            /// <summary>
            /// Initializes name of file operator.
            /// </summary>
            /// <param name="className">The class name of operator.</param>
            /// <param name="displayName">The display name of operator.</param>
            public OperatorName(string className, string displayName)
            {
                _className = className;
                _dispalyName = displayName;
            }

            /// <summary>
            /// Gets name of class.
            /// </summary>
            public string ClassName
            {
                get { return _className; }
            }

            /// <summary>
            /// Gets name to be displayed.
            /// </summary>
            public string DispalyName
            {
                get { return _dispalyName; }
            }
        }
    }
}
